/**
 * 加密工具类 - 与后端RSA+AES混合加密完全兼容
 * 后端: RSA/ECB/PKCS1Padding + AES/ECB/PKCS5Padding
 * 前端: 使用crypto-js和wxmp-rsa实现相同算法
 */

const CryptoJS = require('crypto-js');
import WxmpRsa from 'wxmp-rsa';

const publicKey = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJE/0Ru15nojnI9ObR/mPbC91q
fQGMy8VCq/mVnOFFPbFZMhZ66ftWMv+ST4/ckPtZCj1LZiUQqXv3ouMzlv1a9CDG
Gk3Rb860hJ8wLYTlvA3+YiuN6LUupx/psL6LUUJZ/ub+LoIqSiY+MRu3rZTuqQFX
GDwDbhNt8xTaUNulmwIDAQAB
-----END PUBLIC KEY-----`

const privateKey = `-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMkT/RG7XmeiOcj0
5tH+Y9sL3Wp9AYzLxUKr+ZWc4UU9sVkyFnrp+1Yy/5JPj9yQ+1kKPUtmJRCpe/ei
4zOW/Vr0IMYaTdFvzrSEnzAthOW8Df5iK43otS6nH+mwvotRQln+5v4ugipKJj4x
G7etlO6pAVcYPANuE23zFNpQ26WbAgMBAAECgYAk2gf4dvl/Tsj+XnvrIo9UduE2
ggCFuFbHuFL+q4jRstPNABQEpNtOWfxi6Tf5eYzHLcw8BFVor1cr9Gtlahe2f3p/
JGxd8N8ULhO5Jp46X6KFP6CUMXb/YkFuV4NRUyT+xBKbB5yVm/PvdOhtGHWBVQZX
RgDuPqVoA0nQxvTaoQJBAOVNk/7YMhWNpCyMTD+WMy0RM3EgoZxp8tSMx6ipxdFb
wnoZSLDaAJFiZR6RvcFCCqfBhzosPDPmT0V8aygpEosCQQDgfSj3IUE0ViRgLNMK
p8PupWMpW342Gia3bMbUvlOA6r/+AdcekB3GSaWwLaUTSz5SSpGwD+acNLGJYxAl
nWsxAkEAuNRRiMgHhuwG+4mTJGYTli4ZQwTEf+m+vKlFfqRqOZk3J2gd+b+fWZDw
ZTWguJhdMl+CeteRJ1xrZV0mmtaQhQJBAKTr7nOYT8H2YyTw6V6Tn8MsZ+xTVibD
EZyB4pUa+lfknoYqrfK7J9Sr+Hi1H+hLyA5G0D9Lfz1VDPUE/TDVNJECQDd3LIu7
iLQkdfxKxWHv+M/NRD6FoWvjq/t2RF1Ig9UEN/SwVfWanMz5V0rDbr5cQAFIS8wf
/MRiHdk2XEKnQ90=
-----END PRIVATE KEY-----`

/**
 * 生成16字节AES密钥（与后端AES-128兼容）
 */
function generateAES128Key() {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let result = '';
  for (let i = 0; i < 16; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return result;
}

/**
 * AES加密 - 兼容后端AES/ECB/PKCS5Padding
 */
function aesEncrypt(text, key) {
  try {
    const encrypted = CryptoJS.AES.encrypt(text, CryptoJS.enc.Utf8.parse(key), {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7
    });
    return encrypted.toString();
  } catch (error) {
    console.error('AES加密失败:', error);
    throw new Error('AES加密失败: ' + error.message);
  }
}

/**
 * AES解密 - 兼容后端AES/ECB/PKCS5Padding
 */
function aesDecrypt(encryptedText, key) {
  try {
    const decrypted = CryptoJS.AES.decrypt(encryptedText, CryptoJS.enc.Utf8.parse(key), {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7
    });
    return decrypted.toString(CryptoJS.enc.Utf8);
  } catch (error) {
    console.error('AES解密失败:', error);
    throw new Error('AES解密失败: ' + error.message);
  }
}

/**
 * RSA加密 - 使用wxmp-rsa库兼容微信小程序
 */
function rsaEncrypt(text, publicKey) {
  try {
    const rsa = new WxmpRsa();
    rsa.setPublicKey(publicKey);
    const encrypted = rsa.encryptLong(text);

    if (!encrypted) {
      throw new Error('RSA加密失败');
    }

    return encrypted;
  } catch (error) {
    console.error('RSA加密失败:', error);
    throw new Error('RSA加密失败: ' + error.message);
  }
}

/**
 * RSA解密 - 使用wxmp-rsa库兼容微信小程序
 */
function rsaDecrypt(encryptedText, privateKey) {
  try {
    const rsa = new WxmpRsa();
    rsa.setPrivateKey(privateKey);
    const decrypted = rsa.decryptLong(encryptedText);

    if (!decrypted) {
      throw new Error('RSA解密失败');
    }

    return decrypted;
  } catch (error) {
    console.error('RSA解密失败:', error);
    throw new Error('RSA解密失败: ' + error.message);
  }
}

/**
 * 获取或生成前端密钥对
 */
function getFrontendKeyPair() {
  const fixedKeyPair = {
    publicKey: publicKey,
    privateKey: privateKey
  };
  return fixedKeyPair;
}

/**
 * 将PEM格式公钥转换为纯Base64格式（去除头尾标记）
 */
function convertPEMToBase64(pemKey) {
  return pemKey
    .replace(/-----BEGIN PUBLIC KEY-----/g, '')
    .replace(/-----END PUBLIC KEY-----/g, '')
    .replace(/\s/g, ''); // 移除所有空格和换行符
}

/**
 * 登录数据加密 - 完整的RSA+AES混合加密流程
 */
async function encryptLoginData(loginData, backendPublicKey) {
  try {
    // 1. 生成16字节AES密钥
    const aesKey = generateAES128Key();

    // 2. AES加密登录数据
    const loginDataJson = JSON.stringify(loginData);
    const encryptedData = aesEncrypt(loginDataJson, aesKey);

    // 3. RSA加密AES密钥（需要PEM格式）
    const encryptedKey = rsaEncrypt(aesKey, backendPublicKey);

    // 4. 将PEM格式公钥转换为Base64格式发送给后端
    const PublicKey = getFrontendKeyPair().publicKey;
    const base64PublicKey = convertPEMToBase64(PublicKey);

    

    // 5. 返回符合后端EncryptionBaseParam格式的数据
    return {
      data: encryptedData,
      key: encryptedKey,
      publicKey: base64PublicKey // 发送纯Base64格式给后端
    };
  } catch (error) {
    console.error('登录数据加密失败:', error);
    throw new Error('登录数据加密失败: ' + error.message);
  }
}

/**
 * 解密登录响应数据 - 完整的RSA+AES混合解密流程
 */
function decryptLoginResponse(encryptedResponse) {
  try {


    // 1. 获取前端密钥对
    const frontendKeyPair = getFrontendKeyPair().privateKey;

    // 2. 使用前端RSA私钥解密AES密钥
    const encryptedKey = encryptedResponse.encryptKey;
    if (!encryptedKey) {
      throw new Error('响应中缺少encryptKey字段');
    }


    const aesKey = rsaDecrypt(encryptedKey, frontendKeyPair);


    // 3. 使用AES密钥解密数据
    const encryptedData = encryptedResponse.encryptData;
    if (!encryptedData) {
      throw new Error('响应中缺少encryptData字段');
    }


    const decryptedData = aesDecrypt(encryptedData, aesKey);


    // 4. 解析JSON数据
    let parsedData;
    try {
      parsedData = JSON.parse(decryptedData);
    } catch (parseError) {
      console.warn('解密数据不是JSON格式，返回原始字符串');
      parsedData = decryptedData;
    }

    return {
      success: true,
      data: parsedData
    };

  } catch (error) {
    console.error('解密登录响应失败:', error);
    return {
      success: false,
      error: error.message
    };
  }
}

/**
 * 生成密钥指纹用于调试验证
 */
function generateKeyFingerprint(publicKey) {
  try {
    const keyContent = publicKey
      .replace(/-----BEGIN PUBLIC KEY-----/g, '')
      .replace(/-----END PUBLIC KEY-----/g, '')
      .replace(/\s/g, '');

    let hash = 0;
    for (let i = 0; i < keyContent.length; i++) {
      const char = keyContent.charCodeAt(i);
      hash = ((hash << 5) - hash) + char;
      hash = hash & hash;
    }

    return Math.abs(hash).toString(16).toUpperCase().padStart(8, '0');
  } catch (error) {
    return 'UNKNOWN';
  }
}

/**
 * 检查加密库是否可用
 */
function checkCryptoLibs() {
  const cryptoJSAvailable = typeof CryptoJS !== 'undefined' && CryptoJS.AES;
  const wxmpRsaAvailable = typeof WxmpRsa !== 'undefined';

  return {
    cryptoJS: cryptoJSAvailable,
    wxmpRsa: wxmpRsaAvailable,
    ready: cryptoJSAvailable && wxmpRsaAvailable
  };
}

module.exports = {
  generateAES128Key,
  aesEncrypt,
  aesDecrypt,
  rsaEncrypt,
  rsaDecrypt,
  getFrontendKeyPair,
  convertPEMToBase64,
  encryptLoginData,
  decryptLoginResponse,
  generateKeyFingerprint,
  checkCryptoLibs
};